/*
 * @ProjectName: 编程学习
 * @Copyright:   2019 HangZhou Yi Dev, Ltd. All Right Reserved.
 * @address:     https://yiyuery.github.io/
 * @date:        2019/5/20 20:57
 * @email:       xiazhaoyang@live.com
 * @description: 本内容仅限于编程技术学习使用，转发请注明出处.
 */
package com.example.dependency.io;

import com.google.common.collect.Lists;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;

import java.io.*;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *
 * </p>
 *
 * @author Yi
 * @version v1.0.0
 * @date 2019-06-06 20:57
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人} 2019-06-06
 * @modify reason: {方法名}:{原因}
 * ...
 */
@Slf4j
@Data
public class ReaderAndWrite {

    private InputStreamReader reader;

    private OutputStreamWriter writer;

    private ReaderAndWrite() {
    }

    public static final ReaderAndWrite getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder{
        private final static ReaderAndWrite INSTANCE = new ReaderAndWrite();
    }

    /**
     * 初始化 从指定文件读的 Reader
     *
     * @param source
     */
    public void read(File source) {
        if (!source.exists()) {
            throw new IllegalArgumentException("file be read can't be null");
        }
        try {
            FileInputStream fip = new FileInputStream(source);
            //解决读乱码
            setReader(new InputStreamReader(fip, "UTF-8"));
        } catch (Throwable e) {
            log.error("read file catch exception", e);
        }
    }

    /**
     * 初始化写到指定文件的 Writer
     *
     * @param target
     */
    public void write(File target) {
        try {
            if (!target.exists()) {
                if(!target.getParentFile().exists()){
                    target.getParentFile().mkdirs();
                }
                target.createNewFile(); // 创建新文件
            }
            //解决写乱码
            setWriter(new OutputStreamWriter(new FileOutputStream(target), "UTF-8"));
        } catch (Throwable e) {
            log.error("write file catch exception", e);
        }
    }

    /**
     * 递归读取待写入的文件
     * 遍历根目录下所有文件
     * @param root
     * @param others
     * @return
     */
    public List<File> addFilesToHolder(File root, File... others) {
        List<File> holder = Objects.nonNull(others) && others.length > 0 ? new ArrayList<>(Arrays.asList(others)) : Lists.newArrayList();
        if (root.isDirectory()) {
            for (File f : Objects.requireNonNull(root.listFiles())) {
                holder.addAll(ListUtils.emptyIfNull(addFilesToHolder(f)));
            }
        } else {
            holder.add(root);
        }
        return holder;
    }


    /**
     * 开始合并文件
     * @param allFiles
     * @param module
     */
    public void doCombineTask(List<File> allFiles, String module,String targetPath) throws Exception {
        //打印待合并文件
        if(CollectionUtils.isNotEmpty(allFiles)){
            allFiles.forEach(e->{
                log.info("> "+e.getName());
            });
        }
        log.info("> --------------------------");
        File target = Paths.get(targetPath, module + ".md").toFile();
        getInstance().write(target);
        //写标题
        getInstance().read(target);
        getInstance().getWriter().write("# "+module);
        getInstance().getWriter().write("\r\n");
        getInstance().getWriter().flush();

        for (File file : allFiles) {
            try {
                getInstance().read(file);
                getInstance().markdown("> "+file.getName());
                getInstance().markdown("```"+file.getName().split("\\.")[1]);
                StringBuffer sb = new StringBuffer();
                while (getInstance().getReader().ready()) {
                    // 转成char加到StringBuffer对象中
                    sb.append((char)getInstance().getReader().read());
                }
                getInstance().getWriter().write(sb.toString());
                getInstance().markdown("```");
                getInstance().getWriter().flush();
            }catch (Throwable e){
                log.error("read for write error",e);
            }
        }
    }

    /**
     * 添加markdown标记
     * @param tag
     * @throws Exception
     */
    private void markdown(String tag) throws Exception{
        // \r\n即为换行
        getInstance().getWriter().write("\r\n");
        getInstance().getWriter().write(tag);
        getInstance().getWriter().write("\r\n");
    }
}